/*
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <QSettings>
#include <QDir>
#include <QFileInfo>
#include <QTranslator>
#include <QPixmapCache>
#include <QFileDialog>
#include "settingsframe.h"
#include "log.h"
#include "chanmanager.h"
#include "filteredit.h"
#include "filterlist.h"
#include "filtertext.h"
#include "paths.h"
#include "notification/notificationmanager.h"
#include "chanwatcher.h"

SettingsFrame::SettingsFrame(MainWindow* mainform, Wishmaster::ChanManager* manager, QWidget* parent) : QDialog(parent),
	m_chanmanager(manager)
{
	ui.setupUi(this);
	m_mainform = mainform;
}

SettingsFrame::~SettingsFrame()
{
}

void SettingsFrame::fillForm()
{
	QSettings settings;
	QDir dir(Wishmaster::DefaultPath::i18n());
	QString language = settings.value("language").toString();
	QFileInfoList translationFiles = dir.entryInfoList(QStringList("*.qm"));
	int n = 0;
	ui.cb_language->clear();
	foreach(QFileInfo info, translationFiles)
	{
		ui.cb_language->addItem(info.baseName());
		if(info.baseName() == language)
			ui.cb_language->setCurrentIndex(n);			
		n++;
	}
	
	ui.sb_swappingInterval->setValue(settings.value("threadstorage/swapping_interval", 900).toInt());
	QString format = settings.value("threadstorage/static_image_format", ".jpg").toString();
	if(format == ".jpg")
		ui.rb_jpg->setChecked(true);
	else if(format == ".png")
		ui.rb_png->setChecked(true);
	else
		ui.rb_jpg->setChecked(true);

	ui.cb_hashImages->setChecked(settings.value("imagestorage/checkhash", true).toBool());
	ui.cb_useKeymaps->setChecked(settings.value("general/useKeymaps", true).toBool());
	ui.sb_keepThreads->setValue(settings.value("threadstorage/keepthreads", 300).toInt());

	fillConnectionTab(settings);
	fillAutorefreshTab(settings);
	fillInterfaceTab(settings);

	refreshFilterList();

	ui.cb_enableWipeFilter->setChecked(settings.value("filtration/wipefilter", true).toBool());
}

void SettingsFrame::saveSettings()
{
	QSettings settings;

	settings.setValue("imagestorage/checkhash", ui.cb_hashImages->isChecked());
	
	settings.setValue("threadstorage/swapping_interval", ui.sb_swappingInterval->value());
	if(ui.rb_jpg->isChecked())
		settings.setValue("threadstorage/static_image_format", ".jpg");
	else if(ui.rb_jpg->isChecked())
		settings.setValue("threadstorage/static_image_format", ".png");

	settings.setValue("threadstorage/keepthreads", ui.sb_keepThreads->value());

	settings.setValue("general/useKeymaps", ui.cb_useKeymaps->isChecked());

	saveConnectionTab(settings);
	saveAutorefreshTab(settings);
	saveInterfaceTab(settings);

	settings.setValue("filtration/wipefilter", ui.cb_enableWipeFilter->isChecked());
}

void SettingsFrame::accept()
{
	saveSettings();
	QDialog::accept();
}

void SettingsFrame::languageChanged(const QString& language)
{
	if(!language.isEmpty())
	{
		QSettings settings;
		QTranslator* translator = new QTranslator(this); // Probably, memory leak
		translator->load(language, Wishmaster::DefaultPath::i18n());
		qApp->installTranslator(translator);
		settings.setValue("language", language);
	}
}

bool SettingsFrame::event(QEvent* event)
{
	if(event->type() == QEvent::LanguageChange)
	{
		ui.retranslateUi(this);
		return true;
	}
	return QDialog::event(event);
}

void SettingsFrame::addTextFilter()
{
	FilterEdit dlg(this);
	if(dlg.exec() == QDialog::Accepted)
	{
		Wishmaster::FilterListPtr list = m_chanmanager->globalFilterList();
		list->addTextFilter(dlg.filterName(), dlg.regexp(), dlg.caseInsensitive());
		refreshFilterList();
	}
}

void SettingsFrame::editFilter()
{
	Wishmaster::FilterListPtr list = m_chanmanager->globalFilterList();
	FilterEdit dlg(this);
	Wishmaster::FilterPtr filter = list->filter(ui.lw_postFilters->currentRow());
	if(filter.isNull())
		return;
	
	QSharedPointer<Wishmaster::FilterText> f = filter.dynamicCast<Wishmaster::FilterText>();
	if(f.isNull())
		return;

	dlg.setName(f->name());
	dlg.setRegexp(f->regexp());
	dlg.setCaseInsensitive(f->caseInsensitive());

	if(dlg.exec() == QDialog::Accepted)
	{
		f->setName(dlg.filterName());
		f->setRegexp(dlg.regexp());
		f->setCaseInsensitive(dlg.caseInsensitive());
		refreshFilterList();
	}
}

void SettingsFrame::deleteFilter()
{
	Wishmaster::FilterListPtr list = m_chanmanager->globalFilterList();
	list->deleteFilter(ui.lw_postFilters->currentRow());
	refreshFilterList();
}

void SettingsFrame::refreshFilterList()
{
	ui.lw_postFilters->clear();
	Wishmaster::FilterListPtr list = m_chanmanager->globalFilterList();
	QStringList names = list->listFilters();
	foreach(QString n, names)
	{
		ui.lw_postFilters->addItem(n);
	}
}

void SettingsFrame::fillAutorefreshTab(QSettings& settings)
{
	int policynum = settings.value("autorefresh/policy").toInt();
	switch(policynum)
	{
	case Wishmaster::ChanWatcher::rpAllChans:
		ui.rb_refreshChans->setChecked(true);
		break;

	case Wishmaster::ChanWatcher::rpCurrentChan:
		ui.rb_refreshAB->setChecked(true);
		break;

	case Wishmaster::ChanWatcher::rpCurrentBoard:
		ui.rb_refreshAT->setChecked(true);
		break;

	case Wishmaster::ChanWatcher::rpNothing:
		default:
		ui.rb_refreshDisable->setChecked(true);
		break;
	}
	ui.cb_refreshFirstPageOnly->setChecked(settings.value("autorefresh/onlyfirstpage", true).toBool());
	ui.sb_refreshInterval->setValue(settings.value("autorefresh/interval", 900).toInt());
	ui.sb_watchInterval->setValue(settings.value("watch/interval", 60).toInt());
	ui.cb_lazyAutorefresh->setChecked(settings.value("autorefresh/lazy", false).toBool());
}

void SettingsFrame::saveAutorefreshTab(QSettings& settings)
{
	int policynum = 0;
	if(ui.rb_refreshChans->isChecked())
	{
		policynum = Wishmaster::ChanWatcher::rpAllChans;
	}
	else if(ui.rb_refreshAB->isChecked())
	{
		policynum = Wishmaster::ChanWatcher::rpCurrentChan;
	}
	else if(ui.rb_refreshAT->isChecked())
	{
		policynum = Wishmaster::ChanWatcher::rpCurrentBoard;
	}
	else if(ui.rb_refreshDisable->isChecked())
	{
		policynum = Wishmaster::ChanWatcher::rpNothing;
	}
	settings.setValue("autorefresh/policy", policynum);
	settings.setValue("autorefresh/onlyfirstpage", ui.cb_refreshFirstPageOnly->isChecked());
	settings.setValue("autorefresh/interval", ui.sb_refreshInterval->value());
	settings.setValue("watch/interval", ui.sb_watchInterval->value());
	settings.setValue("autorefresh/lazy", ui.cb_lazyAutorefresh->isChecked());
}

void SettingsFrame::fillConnectionTab(QSettings& settings)
{
	ui.e_proxyhost->setText(settings.value("connection/proxyhost").toString());
	ui.e_proxyport->setText(settings.value("connection/proxyport").toString());
	ui.e_proxyuser->setText(settings.value("connection/proxyuser").toString());
	ui.e_proxypass->setText(settings.value("connection/proxypass").toString());
	ui.e_userAgent->setText(settings.value("connection/useragent", "Wishmaster").toString());

	ui.sb_queueLength->setValue(settings.value("connection/queueLength", 5).toInt());
	ui.cb_picRequestPriority->setChecked(settings.value("connection/picRequestPriority", true).toBool());
}
	
void SettingsFrame::saveConnectionTab(QSettings& settings)
{
	settings.setValue("connection/proxyhost", ui.e_proxyhost->text());
	settings.setValue("connection/proxyport", ui.e_proxyport->text().toUInt());
	settings.setValue("connection/proxyuser", ui.e_proxyuser->text());
	settings.setValue("connection/proxypass", ui.e_proxypass->text());
	settings.setValue("connection/useragent", ui.e_userAgent->text());

	settings.setValue("connection/queueLength", ui.sb_queueLength->value());
	settings.setValue("connection/picRequestPriority", ui.cb_picRequestPriority->isChecked());
}

void SettingsFrame::fillInterfaceTab(QSettings& settings)
{
	QFont postfont = qApp->font();
	if(settings.value("interface/defaultPostFont").isValid())
		postfont = settings.value("interface/defaultPostFont").value<QFont>();
	ui.fcb_postFont->setCurrentFont(postfont);
	ui.sb_postFontSize->setValue(postfont.pointSize());

	QFont headerfont = QFont("Helvetica", 10, 63);
	if(settings.value("interface/defaultHeaderFont").isValid())
		headerfont = settings.value("interface/defaultHeaderFont").value<QFont>();
	ui.fcb_headerFont->setCurrentFont(headerfont);
	ui.sb_headerFontSize->setValue(headerfont.pointSize());

	QFont notefont = QFont("Helvetica", 8, 25);
	if(settings.value("interface/defaultNoteFont").isValid())
		notefont = settings.value("interface/defaultNoteFont").value<QFont>();
	ui.fcb_noteFont->setCurrentFont(notefont);
	ui.sb_noteFontSize->setValue(notefont.pointSize());

	ui.sb_cacheSize->setValue(settings.value("interface/cachesize", 50).toUInt());

	ui.e_styleFile->setText(settings.value("interface/stylefile").toString());

	QString currentNotificator = settings.value("interface/notification/notificator").toString();
	QStringList notificators = Wishmaster::NotificationManager::instance()->notificators();
	ui.cb_notificators->addItems(notificators);
	ui.cb_notificators->setCurrentIndex(ui.cb_notificators->findText(currentNotificator));
	if(ui.cb_notificators->currentIndex() < 0)
		ui.cb_notificators->setCurrentIndex(0);
	updateNotification();

	ui.cb_playSounds->setChecked(Wishmaster::NotificationManager::instance()->isPlaySounds());
	ui.cb_notifyNewMessages->setChecked(settings.value("interface/notification/newmessage/enabled", true).toBool());
	ui.e_notifyNewMessagesFile->setText(settings.value("interface/notification/newmessage/sound", Wishmaster::DefaultPath::shareRoot() + "/sounds/newmsg.wav").toString());
}

void SettingsFrame::saveInterfaceTab(QSettings& settings)
{
	QFont postfont = ui.fcb_postFont->currentFont();
	postfont.setPointSize(ui.sb_postFontSize->value());
	settings.setValue("interface/defaultPostFont", postfont);

	QFont headerfont = ui.fcb_headerFont->currentFont();
	headerfont.setPointSize(ui.sb_headerFontSize->value());
	settings.setValue("interface/defaultHeaderFont", headerfont);

	QFont notefont = ui.fcb_noteFont->currentFont();
	notefont.setPointSize(ui.sb_noteFontSize->value());
	settings.setValue("interface/defaultNoteFont", notefont);

	settings.setValue("interface/cachesize", ui.sb_cacheSize->value());
	QPixmapCache::setCacheLimit(ui.sb_cacheSize->value() * 1024);

	settings.setValue("interface/stylefile", ui.e_styleFile->text());


	settings.setValue("interface/notification/notificator", ui.cb_notificators->currentText());
	if(m_notificatorConfig)
		Wishmaster::NotificationManager::instance()->updateConfig(m_notificatorConfig);

	Wishmaster::NotificationManager::instance()->setPlaySounds(ui.cb_playSounds->isChecked());
	settings.setValue("interface/notification/newmessage/enabled", ui.cb_notifyNewMessages->isChecked());
	settings.setValue("interface/notification/newmessage/sound", ui.e_notifyNewMessagesFile->text());
}

void SettingsFrame::updateNotification()
{
	if(m_notificatorConfig)
		Wishmaster::NotificationManager::instance()->updateConfig(m_notificatorConfig);
	Wishmaster::NotificationManager::instance()->setActiveNotificator(ui.cb_notificators->currentText());
	m_notificatorConfig = QSharedPointer<QWidget>(Wishmaster::NotificationManager::instance()->makeConfig());
	if(ui.f_nConfig->layout())
		delete ui.f_nConfig->layout();
	QHBoxLayout* layout = new QHBoxLayout();
	layout->addWidget(m_notificatorConfig.data());
	ui.f_nConfig->setLayout(layout);
}

void SettingsFrame::wipeFilterToggled(bool b)
{
	//ui.cb_caseSensitive->setEnabled(b);
}

void SettingsFrame::browsePostStyle()
{
	QString fname = QFileDialog::getOpenFileName(this, tr("Select style file..."));
	if(!fname.isNull())
		ui.e_styleFile->setText(fname);
}

void SettingsFrame::browseNewMessagesSound()
{

}

void SettingsFrame::notifyNewMessagesStateChanged(bool b)
{
	ui.e_notifyNewMessagesFile->setEnabled(b);
	ui.b_browseNewMessagesSound->setEnabled(b);
}

